﻿using YiShop.System.Constants;
using YiShop.System.Repositories;
using YiShop.System.Utils;

namespace YiShop.System.Services
{
    public class SysDictTypeService : BaseService<SysDictType, SysDictTypeDto>
    {
        private readonly SysDictDataRepository _sysDictDataRepository;
        private readonly SysDictTypeRepository _sysDictTypeRepository;
        public SysDictTypeService(SysDictTypeRepository sysDictTypeRepository, SysDictDataRepository sysDictDataRepository)
        {
            BaseRepo = _sysDictTypeRepository = sysDictTypeRepository;
            _sysDictDataRepository = sysDictDataRepository;
        }

        public async Task<SysDictType> GetAsync(long id)
        {
            var entity = await FirstOrDefaultAsync(e => e.DictId == id);
            return entity;
        }

        /// <summary>
        /// 根据字典类型查询字典数据
        /// </summary>
        /// <param name="dictType">字典类型</param>
        public async Task<List<SysDictData>> SelectDictDataByTypeAsync(string dictType)
        {
            List<SysDictData> dictDatas = DictUtils.GetDictCache(dictType);
            if (dictDatas.IsNotEmpty())
            {
                return dictDatas;
            }
            dictDatas = await _sysDictDataRepository.SelectDictDataByTypeAsync(dictType);
            if (dictDatas.IsNotEmpty())
            {
                DictUtils.SetDictCache(dictType, dictDatas);
                return dictDatas;
            }
            return null!;
        }

        /// <summary>
        /// 所有字典类型
        /// </summary>
        /// <returns></returns>
        public async Task<List<SysDictType>> SelectDictTypeAllAsync()
        {
            return await GetListAsync(new SysDictTypeDto());
        }

            /// <summary>
    /// 校验字典类型称是否唯一
    /// </summary>
    /// <param name="dict">字典类型</param>
    public async Task<bool> CheckDictTypeUniqueAsync(SysDictTypeDto dict)
    {
        long dictId = dict.DictId;
        SysDictType dictType = await _sysDictTypeRepository.CheckDictTypeUniqueAsync(dict.DictType!);
        if (dictType != null && dictType.DictId != dictId)
        {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /// <summary>
    /// 新增保存字典类型信息
    /// </summary>
    public async Task<bool> InsertDictTypeAsync(SysDictTypeDto dict)
    {
        bool success = await InsertAsync(dict);
        if (success)
        {
            DictUtils.SetDictCache(dict.DictType!, null!);
        }
        return success;
    }

    /// <summary>
    /// 修改保存字典类型信息
    /// </summary>
    public async Task<int> UpdateDictTypeAsync(SysDictTypeDto dict)
    {
        SysDictType oldDict = await GetAsync(dict.DictId);
        await _sysDictDataRepository.UpdateDictDataTypeAsync(oldDict.DictType!, dict.DictType!);
        int row = await UpdateAsync(dict);
        if (row > 0)
        {
            List<SysDictData> dictDatas = await _sysDictDataRepository.SelectDictDataByTypeAsync(dict.DictType!);
            DictUtils.SetDictCache(dict.DictType!, dictDatas);
        }
        return row;
    }

    /// <summary>
    /// 批量删除字典类型信息
    /// </summary>
    public async Task DeleteDictTypeByIdsAsync(long[] dictIds)
    {
        foreach (long dictId in dictIds)
        {
            SysDictType dictType = await GetAsync(dictId);
            if (await _sysDictDataRepository.CountDictDataByTypeAsync(dictType.DictType!) > 0)
            {
                throw new ServiceException($"{dictType.DictName}已分配,不能删除");
            }
            await _sysDictTypeRepository.DeleteAsync(dictId);
            DictUtils.RemoveDictCache(dictType.DictType!);
        }
    }

    /// <summary>
    /// 重置字典缓存数据
    /// </summary>
    public void ResetDictCache()
    {
        ClearDictCache();
        LoadingDictCache();
    }

    /// <summary>
    /// 清空字典缓存数据
    /// </summary>
    public void ClearDictCache()
    {
        DictUtils.ClearDictCache();
    }

    /// <summary>
    /// 加载字典缓存数据
    /// </summary>
    public async void LoadingDictCache()
    {
        SysDictDataDto dto = new SysDictDataDto { Status = Status.Enabled };
        var dictDatas = await _sysDictDataRepository.GetListAsync(dto);
        var dictTypes = dictDatas.Select(d => d.DictType).Distinct().ToList();
        foreach (string dictType in dictTypes)
        {
            DictUtils.SetDictCache(dictType!, dictDatas.Where(d => d.DictType == dictType).ToList());
        }
    }

    }
}
